package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.UserLike;
import com.itheima.enums.FriendsType;
import com.itheima.service.db.UserLikeApi;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.PageInfo;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;


@DubboService
 public class UserLikeApiImpl implements UserLikeApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    public static final String LIKE_REDIS_KEY_PREFIX = "USER_LIKE_";

    public static final String NOT_LIKE_REDIS_KEY_PREFIX = "USER_NOT_LIKE_";
    private Long userId;

    //保存或跟新好友数据
    @Override
    public Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike) {
        try{
            //1.查询数据
            Query query = Query.query(Criteria.where("userId").is(userId)
                    .and("likeUserId").is(likeUserId));
            UserLike userLike = mongoTemplate.findOne(query, UserLike.class);
            //2.如果不存在，保存
            if(userLike == null){
                userLike = new UserLike();
                userLike.setUserId(userId);
                userLike.setIsLike(isLike);
                userLike.setLikeUserId(likeUserId);
                userLike.setCreated(System.currentTimeMillis());

                mongoTemplate.save(userLike);
            }else {
                //3.更新
                Update update = Update.update("isLike", isLike)
                        .set("updated", System.currentTimeMillis());
                mongoTemplate.updateFirst(query,update,UserLike.class);
            }
            return true;
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //查询是否已经喜欢
    @Override
    public Boolean findLike(Long likeUserId,Long userId) {
        Query query = Query.query(Criteria.where("userId").is(userId)
        .and("likeUserId").is(likeUserId));
        UserLike userLike = mongoTemplate.findOne(query, UserLike.class);
        if (userLike == null) {
            return false;
        }
        return userLike.getIsLike();
    }

    @Override
    public void removeFans(Long fanId, Long userId) {
        Query query = new Query(Criteria.where("userId").is(fanId).and("likeUserId").is(userId));
        mongoTemplate.remove(query,UserLike.class);
    }

    //喜欢我的
    @Override
    public PageBeanVo findFanList(Integer page, Integer pagesize, Long userId) {
        Query query = new Query(Criteria.where("LikeUserId").is(userId));
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);
        long count = mongoTemplate.count(query, UserLike.class);
        PageBeanVo pageBeanVo = new PageBeanVo(page, pagesize, count, userLikeList);
        return pageBeanVo;
    }

    @Override
    public String saveUsers(Long userId, Long friendId) {

        if (!ObjectUtil.isAllNotEmpty(userId, friendId)) {
            return null;
        }

        // 检测是否该好友关系是否存在
        Query query = Query.query(Criteria
                .where("userId").is(userId)
                .and("friendId").is(friendId));
        long count = this.mongoTemplate.count(query, Friend.class);
        if (count > 0) { //大于零说明存在 返回
            return null;
        }//不大于零就是没有  做保存操作


        Friend users = new Friend();

        users.setId(ObjectId.get());
        users.setCreated(System.currentTimeMillis());
        users.setUserId(userId);
        users.setFriendId(friendId);

        //注册我与好友的关系
        this.mongoTemplate.save(users);

        //注册好友与我的关系
        users.setId(ObjectId.get());
        users.setUserId(friendId);
        users.setFriendId(userId);
        this.mongoTemplate.save(users);

        return users.getId().toHexString();
    }

    @Override
    public void addFans(Long userId, Long fanId) {
        UserLike userLike = new UserLike();
        userLike.setUserId(fanId);
        userLike.setLikeUserId(userId);
        userLike.setCreated(System.currentTimeMillis());
        mongoTemplate.insert(userLike);
    }



    //我喜欢的
    @Override
    public PageBeanVo findLoveList(Integer page, Integer pagesize, Long userId) {
        Query query = new Query(Criteria.where("userId").is(userId));
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);
        long count = mongoTemplate.count(query, UserLike.class);
        PageBeanVo pageBeanVo = new PageBeanVo(page, pagesize, count, userLikeList);
        return pageBeanVo;
    }
    //查询互相喜欢（1）、喜欢（2）、粉丝（3）数据



    /**
     * 获取不喜欢数据的redis key
     *
     * @param userId
     * @return
     */
    private String getNotLikeRedisKey(Long userId){
        return NOT_LIKE_REDIS_KEY_PREFIX + userId;
    }

    /**
     * 是否喜欢
     *
     * @param userId
     * @param likeUserId
     * @return
     */
    @Override
    public Boolean isLike(Long userId, Long likeUserId){
        String redisKey = this.getLikeRedisKey(userId);
        String hashKey = String.valueOf(likeUserId);
        return this.stringRedisTemplate.opsForHash().hasKey(redisKey, hashKey);
    }

    /**
     * 是否不喜欢
     *
     * @param userId
     * @param likeUserId
     * @return
     */
    public Boolean isNotLike(Long userId, Long likeUserId){
        String redisKey = this.getNotLikeRedisKey(userId);
        String hashKey = String.valueOf(likeUserId);
        return this.stringRedisTemplate.opsForHash().hasKey(redisKey, hashKey);
    }



    @Override
    public List<Long> queryLikeList(Long userId) {
        // 查询redis
        String redisKey = this.getLikeRedisKey(userId);
        Set<Object> keys = this.stringRedisTemplate.opsForHash().keys(redisKey);
        if(CollUtil.isEmpty(keys)){
            return ListUtil.empty();
        }

        List<Long> result = new ArrayList<>(keys.size());
        keys.forEach(o -> result.add(Convert.toLong(o)));
        return result;
    }

    private PageInfo<UserLike> queryList(Query query, Integer page, Integer pageSize) {
        //设置分页
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize,
                Sort.by(Sort.Order.desc("created")));
        query.with(pageRequest);

        List<UserLike> userLikeList = this.mongoTemplate.find(query, UserLike.class);

        PageInfo<UserLike> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(userLikeList);

        return pageInfo;
    }


    @Override
    public Integer findLoveCount(Long userId) {//我喜欢的
        Query query = new Query(Criteria.where("userId").is(userId));
        long count = mongoTemplate.count(query, UserLike.class);
        return Math.toIntExact(count);
    }

    @Override
    public Integer findFanCount(Long userId) {//喜欢我的
        Query query = new Query(Criteria.where("LikeUserId").is(userId));
        long count = mongoTemplate.count(query, UserLike.class);
        return Math.toIntExact(count);
    }


    /**
     * 获取喜欢数据的redis key
     *
     * @param userId
     * @return
     */
    private String getLikeRedisKey(Long userId){
        return LIKE_REDIS_KEY_PREFIX + userId;
    }

//    @Override
//    public List<Long> queryLikeList(Long userId) {
//        // 查询redis
//        String redisKey = this.getLikeRedisKey(userId);
//        Set<Object> keys = this.stringRedisTemplate.opsForHash().keys(redisKey);
//        if(CollUtil.isEmpty(keys)){
//            return ListUtil.empty();
//        }
//
//        List<Long> result = new ArrayList<>(keys.size());
//        keys.forEach(o -> result.add(Convert.toLong(o)));
//        return result;
//    }

    //查询构造结果
    private PageBeanVo pageQuery(Integer page, Integer pagesize, Query query) {
        if (page != 0 && pagesize != 0){
            query.skip((page - 1) * pagesize).limit(pagesize);
        }
        List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);
        long count = mongoTemplate.count(query, UserLike.class);
        return new PageBeanVo(page,pagesize,count,userLikes);
    }


}
